package cn.ulyer.common.json;

import cn.ulyer.common.annotation.Sensitive;
import cn.ulyer.common.enums.SensitiveStrategy;
import cn.ulyer.common.utils.SensitiveUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;


/**
 * json序列化处理类  附带脱敏功能
 * @athor : ulyer
 * @date: 2021/10/27
 */
@Slf4j
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private Sensitive sensitiveInfo;


    public SensitiveSerializer() {
    }

    public SensitiveSerializer(Sensitive sensitive) {
        this.sensitiveInfo = sensitive;
    }


    @Override
    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        log.info("instance:{}",this);
        log.info("annotation:{}",this.sensitiveInfo);
        if (value == null) {
            jsonGenerator.writeNull();
            return;
        }
        if (this.sensitiveInfo == null) {
            jsonGenerator.writeString(value);
            return;
        }
        SensitiveStrategy sensitiveStrategy = this.sensitiveInfo.sensitiveStrategy();
        switch (sensitiveStrategy) {
            case MOBILE_PHONE:
                value = SensitiveUtil.mobilePhone(value);
                break;
            case ADDRESS:
                value = SensitiveUtil.address(value,5);
                break;
            case EMAIL:
                value = SensitiveUtil.email(value);
            case ID_CARD:
                value = SensitiveUtil.idCard(value);
                break;
            case BANK_CARD:
                value = SensitiveUtil.bankCard(value);
                break;
            case CHINESE_NAME:
                value = SensitiveUtil.chineseName(value);
                break;
            case FIXED_PHONE:
                value = SensitiveUtil.fixedPhone(value);
            default:
                // not change
        }
        jsonGenerator.writeString(value);
    }


    @Override
    public Class<String> handledType() {
        return String.class;
    }



    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty == null) {
            return serializerProvider.findNullValueSerializer(null);
        }
        if(String.class.equals(beanProperty.getType().getRawClass())){
            Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
            if(sensitive==null){
                sensitive = beanProperty.getContextAnnotation(Sensitive.class);
            }
            return sensitive==null? this:new SensitiveSerializer(sensitive);
        }
        return this;
    }


}
